home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / geebee.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  4KB  |  146 lines

  1. /****************************************************************************
  2.  *
  3.  * geebee.c
  4.  *
  5.  * sound driver
  6.  * juergen buchmueller <pullmoll@t-online.de>, jan 2000
  7.  *
  8.  ****************************************************************************/
  9.  
  10. #include <math.h>
  11. #include "driver.h"
  12.  
  13. static void *volume_timer = NULL;
  14. static UINT16 *decay = NULL;
  15. static int channel;
  16. static int sound_latch = 0;
  17. static int sound_signal = 0;
  18. static int volume = 0;
  19. static int noise = 0;
  20.  
  21. static void volume_decay(int param)
  22. {
  23.     if( --volume < 0 )
  24.         volume = 0;
  25. }
  26.  
  27. WRITE_HANDLER( geebee_sound_w )
  28. {
  29.     stream_update(channel,0);
  30.     sound_latch = data;
  31.     volume = 0x7fff; /* set volume */
  32.     noise = 0x0000;  /* reset noise shifter */
  33.     /* faster decay enabled? */
  34.     if( sound_latch & 8 )
  35.     {
  36.         /*
  37.          * R24 is 10k, Rb is 0, C57 is 1uF
  38.          * charge time t1 = 0.693 * (R24 + Rb) * C57 -> 0.22176s
  39.          * discharge time t2 = 0.693 * (Rb) * C57 -> 0
  40.          * Then C33 is only charged via D6 (1N914), not discharged!
  41.          * Decay:
  42.          * discharge C33 (1uF) through R50 (22k) -> 0.14058s
  43.          */
  44.         if( volume_timer )
  45.             timer_remove(volume_timer);
  46.         volume_timer = timer_pulse(TIME_IN_HZ(32768/0.14058), 0, volume_decay);
  47.     }
  48.     else
  49.     {
  50.         /*
  51.          * discharge only after R49 (100k) in the amplifier section,
  52.          * so the volume shouldn't very fast and only when the signal
  53.          * is gated through 6N (4066).
  54.          * I can only guess here that the decay should be slower,
  55.          * maybe half as fast?
  56.          */
  57.         if( volume_timer )
  58.             timer_remove(volume_timer);
  59.         volume_timer = timer_pulse(TIME_IN_HZ(32768/0.2906), 0, volume_decay);
  60.     }
  61. }
  62.  
  63. static void geebee_sound_update(int param, INT16 *buffer, int length)
  64. {
  65.     static int vcarry = 0;
  66.     static int vcount = 0;
  67.  
  68.     while (length--)
  69.     {
  70.         *buffer++ = sound_signal;
  71.         /* 1V = HSYNC = 18.432MHz / 3 / 2 / 384 = 8000Hz */
  72.         vcarry -= 18432000 / 3 / 2 / 384;
  73.         while (vcarry < 0)
  74.         {
  75.             vcarry += Machine->sample_rate;
  76.             vcount++;
  77.             /* noise clocked with raising edge of 2V */
  78.             if ((vcount & 3) == 2)
  79.             {
  80.                 /* bit0 = bit0 ^ !bit10 */
  81.                 if ((noise & 1) == ((noise >> 10) & 1))
  82.                     noise = ((noise << 1) & 0xfffe) | 1;
  83.                 else
  84.                     noise = (noise << 1) & 0xfffe;
  85.             }
  86.             switch (sound_latch & 7)
  87.             {
  88.             case 0: /* 4V */
  89.                 sound_signal = (vcount & 0x04) ? decay[volume] : 0;
  90.                 break;
  91.             case 1: /* 8V */
  92.                 sound_signal = (vcount & 0x08) ? decay[volume] : 0;
  93.                 break;
  94.             case 2: /* 16V */
  95.                 sound_signal = (vcount & 0x10) ? decay[volume] : 0;
  96.                 break;
  97.             case 3: /* 32V */
  98.                 sound_signal = (vcount & 0x20) ? decay[volume] : 0;
  99.                 break;
  100.             case 4: /* TONE1 */
  101.                 sound_signal = !(vcount & 0x01) && !(vcount & 0x10) ? decay[volume] : 0;
  102.                 break;
  103.             case 5: /* TONE2 */
  104.                 sound_signal = !(vcount & 0x02) && !(vcount & 0x20) ? decay[volume] : 0;
  105.                 break;
  106.             case 6: /* TONE3 */
  107.                 sound_signal = !(vcount & 0x04) && !(vcount & 0x40) ? decay[volume] : 0;
  108.                 break;
  109.             default: /* NOISE */
  110.                 /* QH of 74164 #4V */
  111.                 sound_signal = (noise & 0x8000) ? decay[volume] : 0;
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117. int geebee_sh_start(const struct MachineSound *msound)
  118. {
  119.     int i;
  120.  
  121.     decay = (UINT16 *)malloc(32768 * sizeof(INT16));
  122.     if( !decay )
  123.         return 1;
  124.  
  125.     for( i = 0; i < 0x8000; i++ )
  126.         decay[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
  127.  
  128.     channel = stream_init("GeeBee", 100, Machine->sample_rate, 0, geebee_sound_update);
  129.     return 0;
  130. }
  131.  
  132. void geebee_sh_stop(void)
  133. {
  134.     if( volume_timer )
  135.         timer_remove(volume_timer);
  136.     volume_timer = NULL;
  137.     if( decay )
  138.         free(decay);
  139.     decay = NULL;
  140. }
  141.  
  142. void geebee_sh_update(void)
  143. {
  144.     stream_update(channel,0);
  145. }
  146.